﻿namespace EnergyGeneratorSimVisualizer.Views
{
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Media;
    using System.Windows.Shapes;

    /// <summary>
    /// Interaction logic for CoilView.xaml
    /// </summary>
    public partial class CoilView : UserControl
    {
        public static readonly DependencyProperty CoilWireColorProperty = DependencyProperty.Register(
            "CoilWireColor",
            typeof(Brush),
            typeof(CoilView),
            new UIPropertyMetadata(Brushes.Red, UpdateDisplay));

        public static readonly DependencyProperty CoilOuterLimitBrushProperty = DependencyProperty.Register(
            "CoilOuterLimitBrush",
            typeof(Brush),
            typeof(CoilView),
            new UIPropertyMetadata(Brushes.DarkGray, UpdateDisplay));

        public static readonly DependencyProperty CoilWindingLateralProperty = DependencyProperty.Register(
            "CoilWindingLateral",
            typeof(int),
            typeof(CoilView),
            new UIPropertyMetadata(5, UpdateDisplay));

        public static readonly DependencyProperty CoilWindingAcrossProperty = DependencyProperty.Register(
            "CoilWindingAcross",
            typeof(int),
            typeof(CoilView),
            new UIPropertyMetadata(3, UpdateDisplay));

        public static readonly DependencyProperty WireDiameterProperty = DependencyProperty.Register(
            "WireDiameter",
            typeof(double),
            typeof(CoilView),
            new UIPropertyMetadata(0.01, UpdateDisplay));

        public static readonly DependencyProperty ZoomFactorProperty = DependencyProperty.Register(
            "ZoomFactor",
            typeof(double),
            typeof(CoilView),
            new UIPropertyMetadata(1000.0, UpdateDisplay));

        /// <summary>
        /// Initializes a new instance of the <see cref="CoilView"/> class.
        /// </summary>
        public CoilView()
        {
            this.InitializeComponent();

            UpdateDisplay(this, new DependencyPropertyChangedEventArgs(WireDiameterProperty, this.WireDiameter, this.WireDiameter));
        }

        public int CoilWindingLateral
        {
            get { return (int)GetValue(CoilWindingLateralProperty); }
            set { SetValue(CoilWindingLateralProperty, value); }
        }

        public int CoilWindingAcross
        {
            get { return (int)GetValue(CoilWindingAcrossProperty); }
            set { SetValue(CoilWindingAcrossProperty, value); }
        }

        public double WireDiameter
        {
            get { return (double)GetValue(WireDiameterProperty); }
            set { SetValue(WireDiameterProperty, value); }
        }

        public Brush CoilWireColor
        {
            get { return (Brush)GetValue(CoilWireColorProperty); }
            set { SetValue(CoilWireColorProperty, value); }
        }

        public Brush CoilOuterLimitBrush
        {
            get { return (Brush)GetValue(CoilOuterLimitBrushProperty); }
            set { SetValue(CoilOuterLimitBrushProperty, value); }
        }

        public double ZoomFactor
        {
            get { return (double)GetValue(ZoomFactorProperty); }
            set { SetValue(ZoomFactorProperty, value); }
        }

        private static void UpdateDisplay(DependencyObject sender, DependencyPropertyChangedEventArgs e)
        {
            var coilView = sender as CoilView;

            if (coilView == null)
            {
                return;
            }

            var grid = new Grid();

            var ellipseStyle = new Style(typeof(Ellipse));
            ellipseStyle.Setters.Add(new Setter(Ellipse.WidthProperty, coilView.WireDiameter * coilView.ZoomFactor));
            ellipseStyle.Setters.Add(new Setter(Ellipse.HeightProperty, coilView.WireDiameter * coilView.ZoomFactor));
            ellipseStyle.Setters.Add(new Setter(Ellipse.FillProperty, coilView.CoilWireColor));
            grid.Resources.Add(typeof(Ellipse), ellipseStyle);

            for (int i = 0; i < coilView.CoilWindingLateral; i++)
            {
                grid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Auto) });
            }

            for (int i = 0; i < coilView.CoilWindingAcross; i++)
            {
                grid.RowDefinitions.Add(new RowDefinition { Height = new GridLength(1, GridUnitType.Auto) });
            }

            for (int i = 0; i < coilView.CoilWindingLateral; i++)
            {
                for (int j = 0; j < coilView.CoilWindingAcross; j++)
                {
                    var ellipse = new Ellipse();

                    Grid.SetColumn(ellipse, i);
                    Grid.SetRow(ellipse, j);

                    grid.Children.Add(ellipse);
                }
            }

            var borderRect = new Rectangle();
            borderRect.Stroke = coilView.CoilOuterLimitBrush;
            Grid.SetColumnSpan(borderRect, int.MaxValue);
            Grid.SetRowSpan(borderRect, int.MaxValue);
            grid.Children.Add(borderRect);

            coilView.Content = grid;
        }
    }
}
